package com.gs.process.core.token;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gs.process.core.user.ProcessUser;
import com.gs.process.core.user.SysUser;
import lombok.Data;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;
import java.util.*;

/**
 * @author: Shuai Guo
 * @description:
 * @date: 2021/9/28
 * @version: 1.0
 */
@Data
public class TokenUtil {
    private static final Logger log = LoggerFactory.getLogger(TokenUtil.class);
    private static JWTVerifier jwtv;

    public TokenUtil() {
    }

    public static String build(SysUser sysUser) {
        log.debug("进入服务:根据 sysUser 生成token,sysUser:{}", sysUser);
        String token = null;

        try {
            Algorithm algorithm = Algorithm.HMAC256("secret");
            Map<String, Object> header = new HashMap<String, Object>();
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            Calendar ca = Calendar.getInstance();
            Date issued = ca.getTime();
            token = JWT.create().withHeader(header).withIssuedAt(issued).withClaim("userId", sysUser.getUserId()).withClaim("userDept", sysUser.getUserDept()).withClaim("username", sysUser.getUsername()).withClaim("userRealName", sysUser.getUserRealName()).withArrayClaim("userRoles", (Long[])sysUser.getUserRoles().toArray(new Long[sysUser.getUserRoles().size()])).sign(algorithm);
        } catch (Exception e) {
            log.error("根据 sysUser 生成token失败,sysUser:{}", sysUser, e);
            token = null;
        }

        log.debug("退出服务:根据 sysUser 生成token,sysUser:{},token:{}", sysUser, token);
        return token;
    }

    public static SysUser parseToUser(String token) {
        log.debug("进入服务:验证token并获取sysUser信息,token:{}", token);
        ProcessUser processUser = null;

        try {
            try {
                if (TokenUtil.jwtv == null) {
                    TokenUtil.jwtv = JWT.require(Algorithm.HMAC256("secret")).build();
                }

                DecodedJWT jwt = null;

                try {
                    jwt = TokenUtil.jwtv.verify(token);
                } catch (Exception e) {
                    log.error("token验证失败，token:{}", token, e);
                    return null;
                }

                String payload = jwt.getPayload();
                if (ObjectUtils.isEmpty(payload)) {
                    log.error("用户信息不能为空,token:{}", token);
                    return null;
                }

                String json = new String(Base64.decodeBase64(payload), "UTF-8");
                ObjectMapper mapper = new ObjectMapper();
                Map<String, Object> map = mapper.readValue(json, Map.class);

                if (map.get("userRoles") != null) {
                    List<Object> roleList = (List)map.get("userRoles");
                    List<Long> roles = new ArrayList();

                    for (Object r : roleList) {
                        roles.add(Long.parseLong(r.toString()));
                    }

                    map.put("userRoles", roles);
                }

                processUser = new ProcessUser();
                BeanUtils.populate(processUser, map);
            } catch (Exception e) {
                processUser = null;
                log.error("验证token并获取sysUser信息失败,token:{}", token, e);
            }

            return processUser;
        } finally {
            log.debug("退出服务:验证token并获取sysUser信息,token:{},sysUser:{}", token, processUser);
        }
    }
}
